//#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include "Mock.h"
#include "SPA_Data_Types.h"
using std::vector;
using namespace std;

struct QueryNode {

		QueryNode* parent;
		vector <QueryNode*> children;
		int entityType; 
		int level;
		int data;
	};

	struct suchThatClause 
	{
		int index;
		int relationshipType;
		vector<Argument> arguments;

	}; 

	struct withClause
	{
		int index;
		vector<Argument> arguments;
		int withType; 
	};

	
	
class Query_Preprocessor
{
private:
	Mock queryObj;
	vector<string> entityTable;
	vector<vector<string>> entityTableMapping;
	vector<string> RelationshipTable;
	vector<string> attrName;
	vector<int> NoOfArguments;
	vector<int> arg1Follows;
	vector<int> arg2Follows;
	vector<int> arg1FollowsT;
	vector<int> arg2FollowsT;
	vector<int> arg1Modifies;
	vector<int> arg2Modifies;
	vector<int> arg1Uses;
	vector<int> arg2Uses;
	vector<int> arg1Parent;
	vector<int> arg2Parent;
	vector<int> arg1ParentT;
	vector<int> arg2ParentT;
	vector<int> arg1Call;
	vector<int> arg2Call;
	vector<int> arg1CallT;
	vector<int> arg2CallT;
	vector<int> arg1Next;
	vector<int> arg2Next;
	vector<int> arg1NextT;
	vector<int> arg2NextT;

	
	
QueryNode* root;
	QueryNode* curr;

public:
	Query_Preprocessor();
	
	void createEntityTable();
	void createEntityRelTable();
	void createMapping(int,vector<string>& variable,struct Result& result);
	int getEntityIndex(string,int&,int&);
	int getRelationshipIndex(string);
	bool checkRelationshipArgumentsValidity(int,int,int);
	int createQueryTree(string,vector<suchThatClause>& suchThat,struct Result& result,vector<withClause>& with); 
	int binarySearch(vector<int>,int,int,int);
	int insertNode(int,int,int);
	int isNumber(string);
	int checkAttributeCompatibility(int arg1,int arg2);
	int checkAttributeName(int,string);
	int tokenize(vector<string>& token,const string& str,const string& delimiters);
	int checkIntArgument(int argument,int argType);
	int checkIndependence(int resultType,int resultIndex, int arg1,int arg2,int argInd1, int argInd2);
};